package com.earthea.application.system.domain.service.impl;

import com.earthea.application.common.constant.Constants;
import com.earthea.application.common.entity.TableDataInfo;
import com.earthea.application.common.utils.ServletUtils;
import com.earthea.application.common.utils.StringUtil;
import com.earthea.application.common.utils.ip.AddressUtils;
import com.earthea.application.system.domain.entity.SysLoginLog;
import com.earthea.application.system.domain.service.ISysLoginLogService;
import com.earthea.application.system.entity.request.SysLoginLogReq;
import com.earthea.application.system.mapper.SysLoginLogMapper;
import com.earthea.common.constant.BaseConstants;
import com.google.common.base.Preconditions;
import eu.bitwalker.useragentutils.UserAgent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 系统访问日志情况信息 服务层处理
 */
@Service
public class SysLoginLogServiceImpl implements ISysLoginLogService {

    private static final Logger SYS_USER_LOGGER = LoggerFactory.getLogger("sys-user");

    @Autowired
    private SysLoginLogMapper sysLoginLogMapper;

    @Qualifier("singleExecute")
    @Autowired
    private ThreadPoolTaskExecutor singleExecute;

    @Override
    public void insert(final String username, final String status, final String message, final Object... args) {
        final UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader(HttpHeaders.USER_AGENT));
        final String ip = ServletUtils.getIpAddr();
        CompletableFuture.runAsync(() -> {
            String address = AddressUtils.getRealAddressByIP(ip);
            StringBuilder info = new StringBuilder();
            info.append(ip).append(BaseConstants.PIPE);
            info.append(address).append(BaseConstants.PIPE);
            info.append(username).append(BaseConstants.PIPE);
            info.append(status).append(BaseConstants.PIPE);
            info.append(message).append(BaseConstants.PIPE);
            // 打印信息到日志
            SYS_USER_LOGGER.info(info.toString(), args);
            // 获取客户端操作系统
            String os = userAgent.getOperatingSystem().getName();
            // 获取客户端浏览器
            String browser = userAgent.getBrowser().getName();
            // 封装对象
            SysLoginLog loginLog = new SysLoginLog();
            loginLog.setUserName(username);
            loginLog.setIpaddr(ip);
            loginLog.setLoginLocation(address);
            loginLog.setBrowser(browser);
            loginLog.setOs(os);
            loginLog.setMsg(message);
            // 日志状态
            if (StringUtil.equalsAny(status, Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
                loginLog.setStatus(Constants.SUCCESS);
            } else if (Constants.LOGIN_FAIL.equals(status)) {
                loginLog.setStatus(Constants.FAIL);
            }
            sysLoginLogMapper.insert(loginLog);
        }, singleExecute);
    }

    @Override
    public TableDataInfo<SysLoginLog> select(SysLoginLogReq req) {
        Preconditions.checkNotNull(req, "req must be not null");
        int total = 0;
        if (req.isPage()) {
            total = sysLoginLogMapper.count(req);
            if (total == 0) {
                return TableDataInfo.EMPTY;
            }
        }
        return new TableDataInfo<>(total, sysLoginLogMapper.select(req));
    }

    @Override
    public int batchDelete(List<Long> infoIds) {
        return sysLoginLogMapper.batchDelete(infoIds);
    }

    @Override
    public void clean() {
        sysLoginLogMapper.clean();
    }
}
